#include "SynchronizedQueue.h"

namespace concurrent {

SynchronizedQueue::SynchronizedQueue()
	: _mutex() {
}

void SynchronizedQueue::push(const T &val) {
	if ( !_mutex.lock() ) 
		throw new SynchronizedQueueException("push::could not obtain lock");
	
	_queue.push(val);

	if ( !_mutex.unlock() )
		throw new SynchronizedQueueException("push::could not release lock");
}

T& SynchronizedQueue::pop() {
	if ( !_mutex.lock() ) 
		throw new SynchonizedQueueException("pop::could not obtain lock");

	if ( _queue.empty() ) {	
		throw new SynchronizedQueueException("pop::empty queue");
	}
	T val = _queue.front();
	_queue.pop();

	if ( !_mutex.unlock() )
		throw new SynchronizedQueueException("pop::could not release lock");
	return val;
}

unsigned int SynchronizedQueue::size() const {
	return _queue.size();
}

bool SynchronizedQueue::empty() const {
	return _queue.empty();
}

SynchronizedQueueException::SynchronizedQueueException(std::string message)
	: _message(message) {
}

virtual const char *SynchronizedQueueException::what() const throw() {
	 return _message.str(); 
}

}
